package cn.test.forkjoin.fj;

import cn.test.forkjoin.arrsum.Utils;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.IntStream;

public class LongSumMain {
    static final int NCPU = Runtime.getRuntime().availableProcessors();

    static long calcSum;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 准备数组
        int[] array = Utils.buildRandomIntArray(100000000);

        Instant now = Instant.now();
        // 单线程计算数组总和
        calcSum = seqSum(array);
        System.out.println("seq sum=" + calcSum);
        System.out.println("执行时间：" + Duration.between(now, Instant.now()).toMillis());

        // 递归任务
        LongSumTask longSumTask = new LongSumTask(0, array.length, array);
        // 构建ForkJoinPool
        ForkJoinPool forkJoinPool = new ForkJoinPool(NCPU);

        now = Instant.now();
        // forkjoin计算数组总和
        ForkJoinTask<Long> result = forkJoinPool.submit(longSumTask);
        System.out.println("forkjoin sum=" + result.get());
        System.out.println("执行时间：" + Duration.between(now, Instant.now()).toMillis());

        forkJoinPool.shutdown();

        now = Instant.now();
        // 并行流计算数组总和
        long sum = IntStream.of(array).asLongStream().parallel().sum();
        System.out.println("IntStream sum=" + sum);
        System.out.println("执行时间：" + Duration.between(now, Instant.now()).toMillis());
    }

    private static long seqSum(int[] array) {
        long sum = 0;
        for (int i = 0; i < array.length; ++i) {
            sum += array[i];
        }
        return sum;
    }
}
